/**
 * 抖音开放平台API路由
 * 处理OAuth认证、用户信息、视频发布、数据分析等功能
 */

import { Router, Request, Response } from 'express';
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import crypto from 'crypto';

const router = Router();

// 抖音开放平台配置
const DOUYIN_CONFIG = {
  baseUrl: 'https://open.douyin.com',
  clientKey: process.env.DOUYIN_CLIENT_KEY || '',
  clientSecret: process.env.DOUYIN_CLIENT_SECRET || '',
};

// 生成签名
function generateSignature(params: Record<string, any>, secret: string): string {
  const sortedKeys = Object.keys(params).sort();
  const queryString = sortedKeys
    .map(key => `${key}=${params[key]}`)
    .join('&');
  
  return crypto
    .createHmac('sha256', secret)
    .update(queryString)
    .digest('hex');
}

// 创建抖音API请求实例
const douyinApi = axios.create({
  baseURL: DOUYIN_CONFIG.baseUrl,
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
    'User-Agent': 'BabyAI-Agent/1.0'
  }
});

// 请求拦截器
douyinApi.interceptors.request.use(
  (config: any) => {
    console.log(`Douyin API Request: ${config.method?.toUpperCase()} ${config.url}`);
    return config;
  },
  (error: any) => {
    console.error('Douyin API Request Error:', error);
    return Promise.reject(error);
  }
);

// 响应拦截器
douyinApi.interceptors.response.use(
  (response: any) => {
    console.log(`Douyin API Response: ${response.status} ${response.config.url}`);
    return response;
  },
  (error: any) => {
    console.error('Douyin API Response Error:', error.response?.data || error.message);
    return Promise.reject(error);
  }
);

/**
 * POST /api/douyin/oauth/access_token
 * 获取访问令牌
 */
router.post('/oauth/access_token', async (req: Request, res: Response) => {
  try {
    const { client_key, client_secret, code, grant_type } = req.body;
    
    if (!client_key || !client_secret || !code) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    const response = await douyinApi.post('/oauth/access_token/', {
      client_key,
      client_secret,
      code,
      grant_type: grant_type || 'authorization_code'
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('获取抖音访问令牌失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取访问令牌失败'
    });
  }
});

/**
 * POST /api/douyin/oauth/refresh_token
 * 刷新访问令牌
 */
router.post('/oauth/refresh_token', async (req: Request, res: Response) => {
  try {
    const { client_key, refresh_token, grant_type } = req.body;
    
    if (!client_key || !refresh_token) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    const response = await douyinApi.post('/oauth/refresh_token/', {
      client_key,
      refresh_token,
      grant_type: grant_type || 'refresh_token'
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('刷新抖音访问令牌失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '刷新访问令牌失败'
    });
  }
});

/**
 * GET /api/douyin/oauth/userinfo
 * 获取用户信息
 */
router.get('/oauth/userinfo', async (req: Request, res: Response) => {
  try {
    const { access_token, open_id } = req.query;
    
    if (!access_token) {
      return res.status(400).json({
        success: false,
        error: '缺少访问令牌'
      });
    }
    
    const params: any = { access_token };
    if (open_id) {
      params.open_id = open_id;
    }
    
    const response = await douyinApi.get('/oauth/userinfo/', { params });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('获取抖音用户信息失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取用户信息失败'
    });
  }
});

/**
 * GET /api/douyin/video/list
 * 获取用户视频列表
 */
router.get('/video/list', async (req: Request, res: Response) => {
  try {
    const { access_token, open_id, cursor = 0, count = 10 } = req.query;
    
    if (!access_token || !open_id) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    const response = await douyinApi.get('/video/list/', {
      params: {
        access_token,
        open_id,
        cursor: Number(cursor),
        count: Number(count)
      }
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('获取抖音视频列表失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取视频列表失败'
    });
  }
});

/**
 * POST /api/douyin/video/upload
 * 发布视频到抖音
 */
router.post('/video/upload', async (req: Request, res: Response) => {
  try {
    const { access_token, video_url, text, ...otherParams } = req.body;
    
    if (!access_token || !video_url) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    const uploadData = {
      access_token,
      video_url,
      text: text || '',
      ...otherParams
    };
    
    const response = await douyinApi.post('/video/upload/', uploadData);
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('发布抖音视频失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '发布视频失败'
    });
  }
});

/**
 * POST /api/douyin/data/external/item
 * 获取视频数据分析
 */
router.post('/data/external/item', async (req: Request, res: Response) => {
  try {
    const { access_token, item_ids, date_type = '7days' } = req.body;
    
    if (!access_token || !item_ids || !Array.isArray(item_ids)) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数或参数格式错误'
      });
    }
    
    const response = await douyinApi.post('/data/external/item/', {
      access_token,
      item_ids,
      date_type
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('获取抖音视频数据分析失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取数据分析失败'
    });
  }
});

/**
 * POST /api/douyin/data/external/fans_profile
 * 获取粉丝数据
 */
router.post('/data/external/fans_profile', async (req: Request, res: Response) => {
  try {
    const { access_token, date_type = '7days' } = req.body;
    
    if (!access_token) {
      return res.status(400).json({
        success: false,
        error: '缺少访问令牌'
      });
    }
    
    const response = await douyinApi.post('/data/external/fans_profile/', {
      access_token,
      date_type
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('获取抖音粉丝数据失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取粉丝数据失败'
    });
  }
});

/**
 * GET /api/douyin/discovery/ent/rank/item
 * 搜索热门视频
 */
router.get('/discovery/ent/rank/item', async (req: Request, res: Response) => {
  try {
    const { access_token, keyword, cursor = 0, count = 10 } = req.query;
    
    if (!access_token || !keyword) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    const response = await douyinApi.get('/discovery/ent/rank/item/', {
      params: {
        access_token,
        keyword,
        cursor: Number(cursor),
        count: Number(count)
      }
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('搜索抖音热门视频失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '搜索热门视频失败'
    });
  }
});

/**
 * GET /api/douyin/discovery/ent/rank/challenge
 * 获取热门话题
 */
router.get('/discovery/ent/rank/challenge', async (req: Request, res: Response) => {
  try {
    const { access_token } = req.query;
    
    if (!access_token) {
      return res.status(400).json({
        success: false,
        error: '缺少访问令牌'
      });
    }
    
    const response = await douyinApi.get('/discovery/ent/rank/challenge/', {
      params: { access_token }
    });
    
    res.json({
      success: true,
      data: response.data
    });
  } catch (error: any) {
    console.error('获取抖音热门话题失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取热门话题失败'
    });
  }
});

/**
 * POST /api/douyin/sync/user
 * 同步用户数据到本地数据库
 */
router.post('/sync/user', async (req: Request, res: Response) => {
  try {
    const { user_info, videos, fans_data } = req.body;
    
    if (!user_info) {
      return res.status(400).json({
        success: false,
        error: '缺少用户信息'
      });
    }
    
    // 这里应该将数据同步到数据库
    // 示例：保存到Supabase或其他数据库
    console.log('同步抖音用户数据:', {
      open_id: user_info.open_id,
      nickname: user_info.nickname,
      video_count: videos?.length || 0,
      fans_data_count: fans_data?.length || 0
    });
    
    // TODO: 实际的数据库同步逻辑
    // await supabase.from('douyin_users').upsert({
    //   open_id: user_info.open_id,
    //   user_data: user_info,
    //   videos: videos,
    //   fans_data: fans_data,
    //   updated_at: new Date().toISOString()
    // });
    
    res.json({
      success: true,
      message: '用户数据同步成功'
    });
  } catch (error: any) {
    console.error('同步抖音用户数据失败:', error);
    res.status(500).json({
      success: false,
      error: '同步用户数据失败'
    });
  }
});

/**
 * POST /api/douyin/schedule
 * 定时发布内容
 */
router.post('/schedule', async (req: Request, res: Response) => {
  try {
    const { content, schedule_time, access_token } = req.body;
    
    if (!content || !schedule_time || !access_token) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    // 这里应该将定时任务存储到队列中
    console.log('创建抖音定时发布任务:', {
      content: content,
      schedule_time: new Date(schedule_time).toISOString()
    });
    
    // TODO: 实际的定时任务逻辑
    // 可以使用Redis队列、数据库定时任务等方式实现
    
    res.json({
      success: true,
      message: '定时发布任务创建成功'
    });
  } catch (error: any) {
    console.error('创建抖音定时发布任务失败:', error);
    res.status(500).json({
      success: false,
      error: '创建定时发布任务失败'
    });
  }
});

/**
 * GET /api/douyin/webhook/verify
 * Webhook验证
 */
router.get('/webhook/verify', (req: Request, res: Response) => {
  try {
    const { signature, timestamp, nonce, msg } = req.query;
    
    if (!signature || !timestamp || !nonce) {
      return res.status(400).json({
        success: false,
        error: '缺少验证参数'
      });
    }
    
    // 验证签名
    const token = process.env.DOUYIN_WEBHOOK_TOKEN || '';
    const expectedSignature = crypto
      .createHash('sha1')
      .update([token, timestamp, nonce].sort().join(''))
      .digest('hex');
    
    if (signature === expectedSignature) {
      res.send(msg || 'success');
    } else {
      res.status(403).json({
        success: false,
        error: '签名验证失败'
      });
    }
  } catch (error: any) {
    console.error('抖音Webhook验证失败:', error);
    res.status(500).json({
      success: false,
      error: 'Webhook验证失败'
    });
  }
});

/**
 * POST /api/douyin/webhook/callback
 * Webhook回调处理
 */
router.post('/webhook/callback', async (req: Request, res: Response) => {
  try {
    const { event, data } = req.body;
    
    console.log('收到抖音Webhook回调:', { event, data });
    
    // 根据不同的事件类型处理
    switch (event) {
      case 'video_publish':
        // 视频发布成功
        console.log('视频发布成功:', data);
        break;
      case 'video_audit':
        // 视频审核结果
        console.log('视频审核结果:', data);
        break;
      case 'fans_change':
        // 粉丝数变化
        console.log('粉丝数变化:', data);
        break;
      default:
        console.log('未知事件类型:', event);
    }
    
    res.json({
      success: true,
      message: '回调处理成功'
    });
  } catch (error: any) {
    console.error('处理抖音Webhook回调失败:', error);
    res.status(500).json({
      success: false,
      error: '回调处理失败'
    });
  }
});

/**
 * GET /api/douyin/stats
 * 获取抖音账号统计数据
 */
router.get('/stats', async (req: Request, res: Response) => {
  try {
    const { access_token, open_id } = req.query;
    
    if (!access_token || !open_id) {
      return res.status(400).json({
        success: false,
        error: '缺少必要参数'
      });
    }
    
    // 获取用户信息
    const userResponse = await douyinApi.get('/oauth/userinfo/', {
      params: { access_token, open_id }
    });
    
    // 获取视频列表
    const videosResponse = await douyinApi.get('/video/list/', {
      params: { access_token, open_id, cursor: 0, count: 100 }
    });
    
    // 获取粉丝数据
    const fansResponse = await douyinApi.post('/data/external/fans_profile/', {
      access_token,
      date_type: '30days'
    });
    
    const userInfo = userResponse.data.data;
    const videos = videosResponse.data.data?.list || [];
    const fansData = fansResponse.data.data?.result_list || [];
    
    // 计算统计数据
    const totalLikes = videos.reduce((sum: number, video: any) => {
      return sum + (video.statistics?.digg_count || 0);
    }, 0);
    
    const totalViews = videos.reduce((sum: number, video: any) => {
      return sum + (video.statistics?.play_count || 0);
    }, 0);
    
    const avgEngagement = videos.length > 0 ? 
      (totalLikes + videos.reduce((sum: number, video: any) => {
        return sum + (video.statistics?.comment_count || 0);
      }, 0)) / videos.length : 0;
    
    res.json({
      success: true,
      data: {
        user_info: userInfo,
        stats: {
          follower_count: userInfo.follower_count,
          following_count: userInfo.following_count,
          aweme_count: userInfo.aweme_count,
          total_likes: totalLikes,
          total_views: totalViews,
          avg_engagement: Math.round(avgEngagement),
          recent_videos: videos.slice(0, 10)
        },
        fans_trend: fansData
      }
    });
  } catch (error: any) {
    console.error('获取抖音账号统计数据失败:', error);
    res.status(500).json({
      success: false,
      error: error.response?.data?.description || '获取统计数据失败'
    });
  }
});

export default router;